<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Exception\Handler;


use App\Exception\MessageException;
use App\Model\UserActionsLog;
use App\Utils\FunUtil;
use Hyperf\Context\Context;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Exception\NotFoundHttpException;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;

class NotFoundHttpExceptionHandler extends ExceptionHandler
{
    #[Inject]
    public ServerRequestInterface $request;

    public function __construct(protected StdoutLoggerInterface $logger)
    {
    }

    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        // 判断被捕获到的异常是希望被捕获的异常
        if ($throwable instanceof NotFoundHttpException) {
            $status = $throwable->getCode();
            $out = json_encode([
                'code' => 404,
                'message' => $throwable->getMessage(),
                'data' => null
            ], JSON_UNESCAPED_UNICODE);
            // 阻止异常冒泡
            $this->stopPropagation();
            $apiLogId = Context::get('apiLogId');
            if (!$apiLogId){
                $params = $this->request->getParsedBody();
                UserActionsLog::query()->insert([
                    'uid' => $params['uid'] ?? 0,
                    'imei' => $params['imei'] ?? '',
                    'ip' => FunUtil::getClientIp(),
                    'actions' => $this->request->getUri()->getPath(),
                    'params' => json_encode($params),
                    'ctime' => time(),
                    'response' => $out
                ]);
            }else{
                UserActionsLog::query()->where('id', $apiLogId)->update(['response' => $out]);
            }
            return $response->withHeader('content-type', 'application/json;charset=utf-8')->withStatus($status)->withBody(new SwooleStream($out));
        }
        // 交给下一个异常处理器
        return $response;

    }

    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}
